# plugins

Used to register Rsbuild plugins.

Async plugin (promise) in the plugins array will be resolved, and falsy values will be ignored.

- **Type:**

```ts
type Falsy = false | null | undefined;

type RsbuildPlugins = (
  | RsbuildPlugin
  | Falsy
  | Promise<RsbuildPlugin | Falsy | RsbuildPlugins>
  | RsbuildPlugins
)[];
```

- **Default:** `undefined`

> Please check out the [Plugin List](/plugins/list/index) page to discover all available plugins.

## Example

For example, register the Stylus plugin in Rsbuild.

- Installing the plugin:

import { PackageManagerTabs } from '@theme';

<PackageManagerTabs command="add @rsbuild/plugin-stylus -D" />

- Registering the plugin:

```ts title="rsbuild.config.ts"
import { defineConfig } from '@rsbuild/core';
import { pluginStylus } from '@rsbuild/plugin-stylus';

export default defineConfig({
  plugins: [pluginStylus()],
});
```

## Execution Order

By default, plugins are executed in the order they appear in the `plugins` array. Built-in Rsbuild plugins are executed before user-registered plugins.

When a plugin internally uses fields that control the order, such as `pre` and `post`, the execution order is adjusted based on them. See [Pre Plugins](/plugins/dev/core#pre-pluginss) for more details.

## Nested Plugins

Rsbuild also supports adding nested plugins. You can pass in an array containing multiple plugins, similar to a plugin preset collection. This is particularly useful for implementing complex functionalities that require a combination of multiple plugins (such as framework integration).

```ts title="rsbuild.config.ts"
function myPlugin() {
  return [fooPlugin(), barPlugin()];
}

export default {
  plugins: [myPlugin()],
};
```

## Local Plugins

If your local code repository contains Rsbuild plugins, you can import them using relative paths.

```ts title="rsbuild.config.ts"
import { defineConfig } from '@rsbuild/core';
import { pluginCustom } from './plugins/pluginCustom';

export default defineConfig({
  plugins: [pluginCustom()],
});
```

## Plugin Options

If a plugin provides custom options, you can pass the configurations through the plugin function's parameters.

```ts title="rsbuild.config.ts"
import { defineConfig } from '@rsbuild/core';
import { pluginStylus } from '@rsbuild/plugin-stylus';

export default defineConfig({
  plugins: [
    pluginStylus({
      stylusOptions: {
        lineNumbers: false,
      },
    }),
  ],
});
```

## Plugin registration phase

It should be noted that plugin registration can only be performed during the Rsbuild initialization phase. You cannot dynamically add other plugins within a plugin through the plugin API:

```ts title=rsbuild.config.ts
// Wrong
function myPlugin() {
  return {
    setup: (api) => {
      api.modifyRsbuildConfig((config, { mergeRsbuildConfig }) => {
        return mergeRsbuildConfig(config, {
          plugins: [fooPlugin(), barPlugin()], // <- it won't work
        });
      });
    },
  };
}

// Correct
function myPlugin() {
  return [fooPlugin(), barPlugin()];
}

export default {
  plugins: [myPlugin()],
};
```

## Rspack Plugins

The `plugins` option is used to register Rsbuild plugins. If you need to register Rspack or Webpack plugins, please use [tools.rspack](/config/tools/rspack).

```ts title="rsbuild.config.ts"
export default {
  // Rsbuild Plugins
  plugins: [pluginStylus()],
  tools: {
    rspack: {
      // Rspack or Webpack Plugins
      plugins: [new SomeWebpackPlugin()],
    },
  },
};
```

## Unplugin

[unplugin](https://github.com/unjs/unplugin) is a unified plugin system for various build tools. You can use plugins implemented based on unplugin in Rsbuild, just import the `/rspack` subpath of the plugin and register it via [tools.rspack](/config/tools/rspack).

Here is an example of using [unplugin-vue-components](https://www.npmjs.com/package/unplugin-vue-components):

```ts
import { defineConfig } from '@rsbuild/core';
import { pluginVue } from '@rsbuild/plugin-vue';
import Components from 'unplugin-vue-components/rspack';

export default defineConfig({
  plugins: [pluginVue()],
  tools: {
    rspack: {
      plugins: [
        Components({
          // options
        }),
      ],
    },
  },
});
```

:::tip
When using the transform hook in unplugin, please use the `transformInclude` hook to match the specified module. When the transform hook matches the `.html` module, it will replace the default EJS transformation of the [html-rspack-plugin](https://github.com/rspack-contrib/html-rspack-plugin).
:::

> Please ensure that the version of `unplugin` package is >= v1.6.0.
